Practical implementation of an IoT application
Introduction This page describes the design of a practical IoT solution. The reflexion process is detailed step by step from the choice of a technology to the implementation of a prototype. The objective is to give an example of how to use the information given on this wiki to conceive an IoT application. Requirements specification The application presented here was designed for the Engineering Faculty of Mons. Its purpose is to measure temperature and humidity in a closed system (an egg incubator) and to report the measurements on a distant server. The sensor must be portable to be used at different places in the city. Here are the technical specifications of the measurements: * temperature range : 0 to 40 °C * humidity range : 0 to 100% * temperature resolution : 0.5 °C * humidity resolution : 1% * sampling period : at most 1 minute Technological choices This section describes the different choices taken for the project. The reasons are detailed according to the information given in the technology-specific pages of the wiki. The identification of the different parts to design is based on the following figure: Communication mean The first design step is the choice of a communication mean. As the application is intended to be portable, only wireless technologies are considered here. The first and main criteria is the range. For a city-wide application, we need a rather long range, but we need to keep the power consumption low because a portable application requires to run on battery, which stores only a limited amount of power. Taking into account these specifications, a suitable choice is a technology from the LPWAN category. Indeed, they provide both long range and low power at the expense of low data rate (which is not a constraint here since we only have to send few data). In this category, we choose to use the LoRa-LoRaWAN technology. Its advantage is to give access to the TTN infrastructure. Indeed, the TTN provides a free LoRaWAN infrastructure which covers the city. This is a big advantage since using this service allows us not to set up our own infrastructure. Sigfox also provides similar services, but its main drawbacks are that it is not free and that its infrastructure is a black box from our point of view. Sensor device We must now choose a device that will collect the data and send them to the TTN. For fast prototyping of the application, we decide to choose a device with high-level API that integrates LoRaWAN standard. The one used for this project is a LoPy device from PyCom. This is a microcontroller with MicroPython interpreter that features different wireless technologies including LoRaWAN. The MicroPython LoRaWAN API will allow us to fast-prototype our application. This microcontroller features GPIO ports that will be easy to connect to any temperature and humidity sensor. Data collection service A data collection service will help us gather the data from the TTN and print them on a graphical interface. Many possibilities exist, including Node-Red and Ubidots. For this project, we have decided to use Node-Red. Indeed, this application is very intuitive and easy to use. Most importantly, it has an module designed for fast integration with the TTN and it has a lot of interesting modules for our application case, as dashboards which will allow us to put the data received in a temporal graphs and a gauges. Setting up the TTN application Setting up a TTN application is relatively easy. For more detailed information about the TTN and its use, see the TTN page. The steps to follow are: * create an account * create an application * create a new device in your application The important parameters given by the TTN interface are the keys needed to identify your application. The only thing that must be manually parametrized is the payload decoder. It can be accessed from the "payload format" tab. It defines the way to interpret the incoming byte payloads to format into structured data. In our application, we impose to send 20 bytes data in each message, containing 5 measurements of the temperature and 5 measurements of the humidity coded on 2 bytes each. The resulting decoder is the following: function Decoder(bytes, port) { var decoded = { temp1 : (bytes0 + 256 * bytes1)/10, hum1 : (bytes2 + 256 * bytes3)/10, temp2 : (bytes4 + 256 * bytes5)/10, hum2 : (bytes6 + 256 * bytes7)/10, temp3 : (bytes8 + 256 * bytes9)/10, hum3 : (bytes10 + 256 * bytes11)/10, temp4 : (bytes12 + 256 * bytes13)/10, hum4 : (bytes14 + 256 * bytes15)/10, temp5 : (bytes16 + 256 * bytes17)/10, hum5 : (bytes18 + 256 * bytes19)/10, }; return decoded; } Designing the circuit Power circuit To be able to use the system that we designed with a 9V battery, we had to do a adapter circuit since the voltage that the LoPy needed was 5 V. To that end, we used the LM317, an 1.5 An adjustable output, positive voltage Regulator. The circuit that we needed to implement to use it was the following: To be able to adjust output voltage precisely, we used for R2 a potentiometer that we adjusted by measuring the output with a voltmeter. Sensor The sensor that we used was the DHT-22. It can measure the temperature in a range of -45 to 125 degree Celsius with a precision of +/-0.2 degree and the humidity between 0 and 100% RH. The sampling period is 2 second. Indeed, these characteristics meets the requirement that we need for our project. There are 4 pins for the device, the first one is for the power line VDD, the second is for the signal data and the forth is for the ground. And they can be seen in the following picture. Programming the LoPy Before starting to use the LoPy, we must first follow the instructions given by the pycom website. https://docs.pycom.io/pycom_esp32/pycom_esp32/getstarted.html This explains how to upgrade the firmware and upload the first code to the LoPy. Our code has two main functionalities: * reading the sensor values * connecting to the TTN and sending data Reading the DHT22 from the LoPy is possible with the following library, available on github. It allows us to read the temperature and humidity measurements, given as integer numbers representing the actual data multiplied by 10. In order to connect to the TTN, we must follow the different steps given by the TTN LoPy guide. The different steps describe how to set up a LoRaWAN connection using the key and ID of our TTN application (for a OTA activation, recommended). An important note is that the application will not work if the device MAC address is not correctly registered on the TTN page. If you use a different LoPy device, you must not change the MicroPython code but be shure to update the device address on the TTN interface. The sampling period of our device must be chosen carefully, in order to comply with the TTN fair use rules. These rules define the recommended duty cycle for connections. This page details the duty cycle limits according to the frequency band used. The duty cycle of our application can be computed using this spreadsheet. As the message length is imposed, we must adapt the time between two messages (and so the sampling time) to comply with the imposed maximum. For battery consideration, some improvements can be implemented in the code. They aim at reducing the LoPy power consumption in order to increase its battery life time. The modifications are the following: * disable the wifi and the bluetooth (to make shure they are turned off) * lower the sending power of the LoRa connection * enable LoRa TX-only mode to save power (this turns off LoRa when a message is not being sent) wlan = WLAN() wlan.deinit() bt = Bluetooth() bt.deinit() lora = LoRa(mode=LoRa.LORAWAN, power_mode=LoRa.TX_ONLY, tx_power=8) These modifications have significant impact on the battery life. Before the improvements, the average consumption was 90mA with peaks of 100mA during the messages transmission. After the modifications, the average consumption fell to 40mA with peaks of 50mA during the transmission. The battery life has thus been doubled thanks to this process. When the WiFi of the LoPy is turned off, it can be difficult to upload a new code to the LoPy. In that case, we can use the soft reset procedure described on the PyCom website. The source code of this project can be found on github. Setting up Node-Red The data are finally collected with Node-Red and processed to be shown on a graphical interface. On the newt figure, we can see the flow developed for our project : The two nodes on the left received the data from the TTN. They were configured with the name and the access key of our application on the TTN named « Chickencheck ». The function node is here to dispatch the data which are received in one piece. Indeed, the devices send ten data at the same time (corresponding to 5 different moments with 10 seconds of delay between each others, each one having a temperature and a humidity measure). That’s why we are delaying some data to ensure that the graph will be drawn with a correct scale in time. The even outputs are the humidity measure, the odd outputs are for the temperatures. These outputs are now linked to graph and to gauge nodes so we can visualize the data. The green nodes are here for a debug purpose. On the following figure, you can see the result appearing on the dashboard : References https://cdn-shop.adafruit.com/datasheets/DHT22.pdf https://www.onsemi.com/pub/Collateral/LM317-D.PDF